﻿/*
 * Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.html or http://CKFinder.com/license
 *
 * The software, this file and its contents are subject to the CKFinder
 * License. Please read the license.txt file before using, installing, copying,
 * modifying or distribute this file or part of its contents. The contents of
 * this file is part of the Source Code of CKFinder.
 */

CKFinder.addPlugin('imageresize', {
    readOnly: false,
    connectorInitialized: function (api, xml) {
        var node = xml.selectSingleNode('Connector/PluginsInfo/imageresize/@smallThumb');
        if (node)
            CKFinder.config.imageresize_thumbSmall = node.value;

        node = xml.selectSingleNode('Connector/PluginsInfo/imageresize/@mediumThumb');
        if (node)
            CKFinder.config.imageresize_thumbMedium = node.value;

        node = xml.selectSingleNode('Connector/PluginsInfo/imageresize/@largeThumb');
        if (node)
            CKFinder.config.imageresize_thumbLarge = node.value;
    },
    uiReady: function (api) {
        var regexExt = /^(.*)\.([^\.]+)$/,
            regexFileName = /^(.*?)(?:_\d+x\d+)?\.([^\.]+)$/,
            regexGetSize = /^\s*(\d+)(px)?\s*$/i,
            regexGetSizeOrEmpty = /(^\s*(\d+)(px)?\s*$)|^$/i,
            imageDimension = {width: 0, height: 0},
            file,
            doc;

        var updateFileName = function (dialog) {
            var width = dialog.getValueOf('tab1', 'width') || 0,
                height = dialog.getValueOf('tab1', 'height') || 0,
                e = dialog.getContentElement('tab1', 'createNewBox');

            if (width && height) {
                var matches = file.name.match(regexFileName);
                dialog.setValueOf('tab1', 'fileName', matches[1] + '_' + width + 'x' + height);
                e.getElement().show();
            }
            else
                e.getElement().hide();
        };

        var onSizeChange = function () {
            var value = this.getValue(),	// This = input element.
                dialog = this.getDialog(),
                maxWidth = api.config.imagesMaxWidth,
                maxHeight = api.config.imagesMaxHeight,
                aMatch = value.match(regexGetSize),
                width = imageDimension.width,
                height = imageDimension.height,
                newHeight,
                newWidth;

            if (aMatch)
                value = aMatch[1];

            if (!api.config.imageresize_allowEnlarging) {
                if (width && width < maxWidth)
                    maxWidth = width;

                if (height && height < maxHeight)
                    maxHeight = height;
            }

            if (maxHeight > 0 && this.id == 'height' && value > maxHeight) {
                value = maxHeight;
                dialog.setValueOf('tab1', 'height', value);
            }

            if (maxWidth > 0 && this.id == 'width' && value > maxWidth) {
                value = maxWidth;
                dialog.setValueOf('tab1', 'width', value);
            }

            // Only if ratio is locked
            if (dialog.lockRatio && width && height) {
                if (this.id == 'height') {
                    if (value && value != '0')
                        value = Math.round(width * (value / height));

                    if (!isNaN(value)) {
                        // newWidth > maxWidth
                        if (maxWidth > 0 && value > maxWidth) {
                            value = maxWidth;
                            newHeight = Math.round(height * (value / width));
                            dialog.setValueOf('tab1', 'height', newHeight);
                        }

                        dialog.setValueOf('tab1', 'width', value);
                    }
                }
                else	//this.id = txtWidth.
                {
                    if (value && value != '0')
                        value = Math.round(height * (value / width));

                    if (!isNaN(value)) {
                        // newHeight > maxHeight
                        if (maxHeight > 0 && value > maxHeight) {
                            value = maxHeight;
                            newWidth = Math.round(width * (value / height));
                            dialog.setValueOf('tab1', 'width', newWidth);
                        }

                        dialog.setValueOf('tab1', 'height', value);
                    }
                }
            }

            updateFileName(dialog);
        };

        var resetSize = function (dialog) {
            if (imageDimension.width && imageDimension.height) {
                dialog.setValueOf('tab1', 'width', imageDimension.width);
                dialog.setValueOf('tab1', 'height', imageDimension.height);
                updateFileName(dialog);
            }
        };

        var switchLockRatio = function (dialog, value) {
            var doc = dialog.getElement().getDocument(),
                ratioButton = doc.getById('btnLockSizes');

            if (imageDimension.width && imageDimension.height) {
                if (value == 'check')	// Check image ratio and original image ratio.
                {
                    var width = dialog.getValueOf('tab1', 'width'),
                        height = dialog.getValueOf('tab1', 'height'),
                        originalRatio = imageDimension.width * 1000 / imageDimension.height,
                        thisRatio = width * 1000 / height;
                    dialog.lockRatio = false;	// Default: unlock ratio

                    if (!width && !height)
                        dialog.lockRatio = true; // If someone didn't start typing, lock ratio.
                    else if (!isNaN(originalRatio) && !isNaN(thisRatio)) {
                        if (Math.round(originalRatio) == Math.round(thisRatio))
                            dialog.lockRatio = true;
                    }
                }
                else if (value != undefined)
                    dialog.lockRatio = value;
                else
                    dialog.lockRatio = !dialog.lockRatio;
            }
            else if (value != 'check')	// I can't lock ratio if ratio is unknown.
                dialog.lockRatio = false;

            if (dialog.lockRatio)
                ratioButton.removeClass('ckf_btn_unlocked');
            else
                ratioButton.addClass('ckf_btn_unlocked');

            return dialog.lockRatio;
        };

        CKFinder.dialog.add('resizeDialog', function (api) {
            return {
                title: api.lang.Imageresize.dialogTitle.replace('%s', api.getSelectedFile().name),
                // TODO resizable : CKFinder.DIALOG_RESIZE_BOTH
                minWidth: CKFinder.env.webkit ? 290 : 390,
                minHeight: 230,
                onShow: function () {
                    var dialog = this,
                        thumbSmall = CKFinder.config.imageresize_thumbSmall,
                        thumbMedium = CKFinder.config.imageresize_thumbMedium,
                        thumbLarge = CKFinder.config.imageresize_thumbLarge;

                    doc = dialog.getElement().getDocument();
                    file = api.getSelectedFile();

                    this.setTitle(api.lang.Imageresize.dialogTitle.replace('%s', file.name));

                    var previewImg = doc.getById('previewImage');
                    var sizeSpan = doc.getById('imageSize');

                    // Thumbnails should be limited to a reasonable value (#1020).
                    previewImg.setAttribute('src', file.getThumbnailUrl(true));
                    previewImg.on('load', function () {
                        previewImg.removeStyle('width');
                        previewImg.removeStyle('height');
                        var width = previewImg.$.width,
                            height = previewImg.$.height;
                        previewImg.hide();
                        if (CKFinder.env.ie6Compat) {
                            if (width > height)
                                previewImg.setStyles({
                                    width: 100 + 'px',
                                    height: Math.round(height / (width / 100)) + 'px'
                                });
                            else
                                previewImg.setStyles({
                                    height: 100 + 'px',
                                    width: Math.round(width / (height / 100)) + 'px'
                                });
                        }
                        else {
                            previewImg.removeStyle('max-width');
                            previewImg.removeStyle('max-height');
                            if (width > height)
                                previewImg.setStyle('max-width', '100px');
                            else
                                previewImg.setStyle('max-height', '100px');
                        }
                        previewImg.show();
                    });

                    var updateImgDimension = function (width, height) {
                        if (!width || !height) {
                            sizeSpan.setText('');
                            return;
                        }

                        imageDimension.width = width;
                        imageDimension.height = height;
                        sizeSpan.setText(width + ' x ' + height + ' px');
                        CKFinder.tools.setTimeout(function () {
                            switchLockRatio(dialog, 'check');
                        }, 0, dialog);
                    };

                    api.connector.sendCommand('ImageResizeInfo', {
                            fileName: file.name
                        },
                        function (xml) {
                            if (xml.checkError())
                                return;
                            var width = xml.selectSingleNode('Connector/ImageInfo/@width'),
                                height = xml.selectSingleNode('Connector/ImageInfo/@height'),
                                result;

                            if (width && height) {
                                width = parseInt(width.value, 10);
                                height = parseInt(height.value, 10);
                                updateImgDimension(width, height);

                                var checkThumbs = function (id, size) {
                                    if (!size)
                                        return;

                                    var reThumb = /^(\d+)x(\d+)$/;
                                    result = reThumb.exec(size);

                                    var el = dialog.getContentElement('tab1', id);
                                    if (0 + result[1] > width && 0 + result[2] > height) {
                                        el.disable();
                                        el.getElement().setAttribute('title', api.lang.Imageresize.imageSmall).addClass('cke_disabled');
                                    }
                                    else {
                                        el.enable();
                                        el.getElement().setAttribute('title', '').removeClass('cke_disabled');
                                    }
                                };

                                checkThumbs('smallThumb', thumbSmall);
                                checkThumbs('mediumThumb', thumbMedium);
                                checkThumbs('largeThumb', thumbLarge);
                            }
                        },
                        file.folder.type,
                        file.folder
                    );

                    if (!thumbSmall)
                        dialog.getContentElement('tab1', 'smallThumb').getElement().hide();

                    if (!thumbMedium)
                        dialog.getContentElement('tab1', 'mediumThumb').getElement().hide();

                    if (!thumbLarge)
                        dialog.getContentElement('tab1', 'largeThumb').getElement().hide();

                    if (!thumbSmall && !thumbMedium && !thumbLarge)
                        dialog.getContentElement('tab1', 'thumbsLabel').getElement().hide();

                    dialog.setValueOf('tab1', 'fileName', file.name);
                    dialog.getContentElement('tab1', 'fileNameExt').getElement().setHtml('.' + file.ext);
                    dialog.getContentElement('tab1', 'width').focus();
                    dialog.getContentElement('tab1', 'fileName').setValue('');
                    dialog.getContentElement('tab1', 'createNewBox').getElement().hide();
                    updateImgDimension(0, 0);
                },
                onOk: function () {
                    var dialog = this,
                        width = dialog.getValueOf('tab1', 'width'),
                        height = dialog.getValueOf('tab1', 'height'),
                        small = dialog.getValueOf('tab1', 'smallThumb'),
                        medium = dialog.getValueOf('tab1', 'mediumThumb'),
                        large = dialog.getValueOf('tab1', 'largeThumb'),
                        fileName = dialog.getValueOf('tab1', 'fileName'),
                        createNew = dialog.getValueOf('tab1', 'createNew');

                    if (width && !height) {
                        api.openMsgDialog('', api.lang.Imageresize.invalidHeight);
                        return false;
                    }
                    else if (!width && height) {
                        api.openMsgDialog('', api.lang.Imageresize.invalidWidth);
                        return false;
                    }
                    if (!api.config.imageresize_allowEnlarging && (parseInt(width, 10) > imageDimension.width || parseInt(height, 10) > imageDimension.height)) {
                        var str = api.lang.Imageresize.sizeTooBig;
                        api.openMsgDialog('', str.replace('%size', imageDimension.width + 'x' + imageDimension.height));
                        return false;
                    }

                    if ((width && height) || small || medium || large) {
                        if (!createNew)
                            fileName = file.name;

                        api.connector.sendCommandPost('ImageResize', null, {
                                width: width,
                                height: height,
                                fileName: file.name,
                                newFileName: fileName + '.' + file.ext,
                                overwrite: createNew ? 0 : 1,
                                small: small ? 1 : 0,
                                medium: medium ? 1 : 0,
                                large: large ? 1 : 0
                            },
                            function (xml) {
                                if (xml.checkError())
                                    return;
                                api.openMsgDialog('', api.lang.Imageresize.resizeSuccess);
                                api.refreshOpenedFolder();
                            },
                            file.folder.type,
                            file.folder
                        );
                    }
                    return undefined;
                },
                contents: [
                    {
                        id: 'tab1',
                        label: '',
                        title: '',
                        expand: true,
                        padding: 0,
                        elements:
                            [
                                {
                                    type: 'hbox',
                                    // The dialog window looks weird on Webkit (#1021)
                                    widths: [(CKFinder.env.webkit ? 130 : 180) + 'px', (CKFinder.env.webkit ? 250 : 280) + 'px'],
                                    children:
                                        [
                                            {
                                                type: 'vbox',
                                                children:
                                                    [
                                                        {
                                                            type: 'html',
                                                            html: '' +
                                                            '<style type="text/css">' +
                                                            'a.ckf_btn_reset' +
                                                            '{' +
                                                            'float: right;' +
                                                            'background-position: 0 -32px;' +
                                                            'background-image: url("' + CKFinder.getPluginPath('imageresize') + 'images/mini.gif");' +
                                                            'width: 16px;' +
                                                            'height: 16px;' +
                                                            'background-repeat: no-repeat;' +
                                                            'border: 1px none;' +
                                                            'font-size: 1px;' +
                                                            '}' +

                                                            'a.ckf_btn_locked,' +
                                                            'a.ckf_btn_unlocked' +
                                                            '{' +
                                                            'float: left;' +
                                                            'background-position: 0 0;' +
                                                            'background-image: url("' + CKFinder.getPluginPath('imageresize') + 'images/mini.gif");' +
                                                            'width: 16px;' +
                                                            'height: 16px;' +
                                                            'background-repeat: no-repeat;' +
                                                            'border: none 1px;' +
                                                            'font-size: 1px;' +
                                                            '}' +

                                                            'a.ckf_btn_unlocked' +
                                                            '{' +
                                                            'background-position: 0 -16px;' +
                                                            'background-image: url("' + CKFinder.getPluginPath('imageresize') + '/images/mini.gif");' +
                                                            '}' +

                                                            '.ckf_btn_over' +
                                                            '{' +
                                                            'border: outset 1px;' +
                                                            'cursor: pointer;' +
                                                            'cursor: hand;' +
                                                            '}' +
                                                            '</style>' +

                                                            '<div style="height:110px;padding:7px">' +
                                                            '<img id="previewImage" src="" style="margin-bottom:4px; max-width: 100px; max-height: 100px;" /><br />' +
                                                            '<span style="font-size:9px;" id="imageSize"></span>' +
                                                            '</div>'
                                                        },
                                                        {
                                                            type: 'html',
                                                            id: 'thumbsLabel',
                                                            html: '<strong>' + api.lang.Imageresize.thumbnailNew + '</strong>'
                                                        },
                                                        {
                                                            type: 'checkbox',
                                                            id: 'smallThumb',
                                                            checked: false,
                                                            label: api.lang.Imageresize.thumbnailSmall.replace('%s', CKFinder.config.imageresize_thumbSmall)
                                                        },
                                                        {
                                                            type: 'checkbox',
                                                            id: 'mediumThumb',
                                                            checked: false,
                                                            label: api.lang.Imageresize.thumbnailMedium.replace('%s', CKFinder.config.imageresize_thumbMedium)
                                                        },
                                                        {
                                                            type: 'checkbox',
                                                            id: 'largeThumb',
                                                            checked: false,
                                                            label: api.lang.Imageresize.thumbnailLarge.replace('%s', CKFinder.config.imageresize_thumbLarge)
                                                        }
                                                    ]
                                            },
                                            {
                                                type: 'vbox',
                                                children:
                                                    [
                                                        {
                                                            type: 'html',
                                                            html: '<strong>' + api.lang.Imageresize.newSize + '</strong>'
                                                        },
                                                        {
                                                            type: 'hbox',
                                                            widths: ['80%', '20%'],
                                                            children:
                                                                [
                                                                    {
                                                                        type: 'vbox',
                                                                        children:
                                                                            [
                                                                                {
                                                                                    type: 'text',
                                                                                    labelLayout: 'horizontal',
                                                                                    label: api.lang.Imageresize.width,
                                                                                    onKeyUp: onSizeChange,
                                                                                    validate: function () {
                                                                                        var value = this.getValue();
                                                                                        if (value) {
                                                                                            var aMatch = value.match(regexGetSize);
                                                                                            if (!aMatch || parseInt(aMatch[1], 10) < 1) {
                                                                                                api.openMsgDialog('', api.lang.Imageresize.invalidWidth);
                                                                                                return false;
                                                                                            }
                                                                                        }
                                                                                        return true;
                                                                                    },
                                                                                    id: 'width'
                                                                                },
                                                                                {
                                                                                    type: 'text',
                                                                                    labelLayout: 'horizontal',
                                                                                    label: api.lang.Imageresize.height,
                                                                                    onKeyUp: onSizeChange,
                                                                                    validate: function () {
                                                                                        var value = this.getValue();
                                                                                        if (value) {
                                                                                            var aMatch = value.match(regexGetSize);
                                                                                            if (!aMatch || parseInt(aMatch[1], 10) < 1) {
                                                                                                api.openMsgDialog('', api.lang.Imageresize.invalidHeight);
                                                                                                return false;
                                                                                            }
                                                                                        }
                                                                                        return true;
                                                                                    },
                                                                                    id: 'height'
                                                                                }
                                                                            ]
                                                                    },
                                                                    {
                                                                        type: 'html',
                                                                        onLoad: function () {
                                                                            var doc = this.getElement().getDocument(),
                                                                                dialog = this.getDialog();
                                                                            // Activate Reset button
                                                                            var resetButton = doc.getById('btnResetSize'),
                                                                                ratioButton = doc.getById('btnLockSizes');
                                                                            if (resetButton) {
                                                                                resetButton.on('click', function (evt) {
                                                                                    resetSize(this);
                                                                                    evt.data.preventDefault();
                                                                                }, dialog);
                                                                                resetButton.on('mouseover', function () {
                                                                                    this.addClass('ckf_btn_over');
                                                                                }, resetButton);
                                                                                resetButton.on('mouseout', function () {
                                                                                    this.removeClass('ckf_btn_over');
                                                                                }, resetButton);
                                                                            }
                                                                            // Activate (Un)LockRatio button
                                                                            if (ratioButton) {
                                                                                ratioButton.on('click', function (evt) {
                                                                                    var locked = switchLockRatio(this),
                                                                                        width = this.getValueOf('tab1', 'width');

                                                                                    if (imageDimension.width && width) {
                                                                                        var height = imageDimension.height / imageDimension.width * width;
                                                                                        if (!isNaN(height)) {
                                                                                            this.setValueOf('tab1', 'height', Math.round(height));
                                                                                            updateFileName(dialog);
                                                                                        }
                                                                                    }
                                                                                    evt.data.preventDefault();
                                                                                }, dialog);
                                                                                ratioButton.on('mouseover', function () {
                                                                                    this.addClass('ckf_btn_over');
                                                                                }, ratioButton);
                                                                                ratioButton.on('mouseout', function () {
                                                                                    this.removeClass('ckf_btn_over');
                                                                                }, ratioButton);
                                                                            }
                                                                        },
                                                                        html: '<div style="margin-top:4px">' +
                                                                        '<a href="javascript:void(0)" tabindex="-1" title="' + api.lang.Imageresize.lockRatio + '" class="ckf_btn_locked ckf_btn_unlocked" id="btnLockSizes"></a>' +
                                                                        '<a href="javascript:void(0)" tabindex="-1" title="' + api.lang.Imageresize.resetSize + '" class="ckf_btn_reset" id="btnResetSize"></a>' +
                                                                        '</div>'
                                                                    }
                                                                ]
                                                        },
                                                        {
                                                            type: 'vbox',
                                                            id: 'createNewBox',
                                                            hidden: true,
                                                            children:
                                                                [
                                                                    {
                                                                        type: 'checkbox',
                                                                        checked: true,
                                                                        id: 'createNew',
                                                                        label: api.lang.Imageresize.newImage,
                                                                        'default': true,
                                                                        onChange: function () {
                                                                            var dialog = this.getDialog();
                                                                            var filenameInput = dialog.getContentElement('tab1', 'fileName');
                                                                            if (filenameInput) {
                                                                                if (!this.getValue())
                                                                                    filenameInput.getElement().hide();
                                                                                else
                                                                                    filenameInput.getElement().show();
                                                                            }
                                                                        }
                                                                    },
                                                                    {
                                                                        type: 'hbox',
                                                                        widths: ['90%', '10%'],
                                                                        padding: 0,
                                                                        children:
                                                                            [
                                                                                {
                                                                                    type: 'text',
                                                                                    label: '',
                                                                                    validate: function () {
                                                                                        var dialog = this.getDialog(),
                                                                                            createNew = dialog.getContentElement('tab1', 'createNew'),
                                                                                            value = this.getValue();

                                                                                        if (createNew && dialog.getValueOf('tab1', 'width') && dialog.getValueOf('tab1', 'height')) {
                                                                                            if (!value) {
                                                                                                api.openMsgDialog('', api.lang.Imageresize.invalidName);
                                                                                                return false;
                                                                                            }
                                                                                        }
                                                                                        return true;
                                                                                    },
                                                                                    id: 'fileName'
                                                                                },
                                                                                {
                                                                                    type: 'html',
                                                                                    html: '',
                                                                                    id: 'fileNameExt',
                                                                                    onLoad: function () {
                                                                                        this.getElement().getParent().setStyles({
                                                                                            'vertical-align': 'bottom',
                                                                                            'padding-bottom': '2px'
                                                                                        });
                                                                                    }
                                                                                }
                                                                            ]
                                                                    }
                                                                ]
                                                        }
                                                    ]
                                            }
                                        ]
                                }
                            ]
                    }
                ],
                // TODO http://dev.fckeditor.net/ticket/4750
                buttons: [CKFinder.dialog.okButton, CKFinder.dialog.cancelButton]
            };
        });

        api.addFileContextMenuOption({
                label: api.lang.Imageresize.contextMenuName,
                command: 'resizeImage'
            }, function (api, file) {
                api.openDialog('resizeDialog');
            },
            function (file) {
                // Disable for files other than images.
                if (!file.isImage() || !api.getSelectedFolder().type)
                    return false;
                if (file.folder.acl.fileDelete && file.folder.acl.fileUpload)
                    return true;
                else
                    return -1;
            }
        );
    }
});
